home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / fp / ifp_unix.lzh / ifp / interp / string.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-23  |  7.8 KB  |  348 lines

  1.  
  2. /****** string.c ******************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                         Version: 0.5                 **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison       Date:  Jan 20, 1987          **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23. #include <stdio.h>
  24. #include "struct.h"
  25. #include "node.h"
  26. #include "umax.h"
  27. #include "string.h"
  28.  
  29. /* Single character strings, CharString [0] = null string */
  30. StrPtr *CharString;  
  31.  
  32. /* Free string segments have SRef = 1 and are linked by StrNext link */
  33. StrPtr FreeString = NULL;
  34.  
  35. /*
  36.  * NewSCell
  37.  *
  38.  * return pointer to fresh string cell with SRef = 1 and StrNext = NULL.
  39.  *
  40.  * A SysError may occur, in which case the NULL pointer is returned.
  41.  */
  42. private StrPtr NewSCell ()
  43.    {
  44.       extern StrPtr AllocStrPage ();
  45.       register StrPtr S;
  46.  
  47.       semaphore_wait (SRefSemaphore);
  48.       if (FreeString != NULL || (FreeString = AllocStrPage ()) != NULL) {
  49.      S = FreeString;
  50.      FreeString = S->StrNext;
  51.      S->SRef = 1;
  52.      S->StrNext = NULL;
  53.       }
  54.       else {
  55.      SysError = NO_STR_FREE;
  56.      printf ("NO MORE STRING CELLS LEFT\n");
  57.      S = NULL;
  58.       }
  59.       semaphore_signal (SRefSemaphore);
  60.       return S;
  61.    }
  62.  
  63. /*
  64.  * CPInit
  65.  *
  66.  * Initialize a character pointer.
  67.  */
  68. void CPInit (U,S)
  69.    register CharPtr *U;
  70.    register StrPtr *S;
  71.    {
  72.       if ((U->CPSeg = *(U->CPStr = S)) == NULL) U->CPCount = 0;
  73.       else {
  74.      U->CPCount = StrHeadLen;
  75.      U->CPChar = (*S)->StrChar;
  76.       }
  77.    }
  78.  
  79. /*
  80.  * CPRead
  81.  *
  82.  * Read up to N-1 characters from and advance a character pointer.
  83.  * '\0' is returned as the last character of the string.
  84.  *
  85.  * Input
  86.  *     *U = character pointer
  87.  *     Buf = buffer into which to read characters
  88.  *     N-1 = number of characters to read
  89.  *
  90.  * Output
  91.  *      result = true if characters were read, 0 if end of string.
  92.  *      Buf = string of characters terminated by '\0'
  93.  */
  94. boolean CPRead (U,Buf,N)
  95.    register CharPtr *U;
  96.    register char *Buf;
  97.    register int N;
  98.    {
  99.       register char *S;
  100.       register int K;
  101.  
  102.       if (!U->CPCount && (NULL==U->CPSeg || NULL==U->CPSeg->StrNext) ||
  103.       !*(S = U->CPChar)) {
  104.  
  105.      *Buf = '\0';
  106.      return 0;
  107.  
  108.       } else {
  109.  
  110.      --N;
  111.      while (N > 0) {
  112.         K = U->CPCount;
  113.         if (K > N) K = N;
  114.         N -= K;
  115.         U->CPCount -= K;
  116.         while (--K >= 0) *Buf++ = *S++;
  117.         if (!U->CPCount) {
  118.            if (NULL == (U->CPSeg = U->CPSeg->StrNext)) break;
  119.            else {
  120.           U->CPCount = StrTailLen;
  121.           S = U->CPSeg->StrChar;
  122.            }
  123.         }
  124.      }
  125.      U->CPChar = S;
  126.      *Buf = '\0';
  127.      return 1;
  128.       }
  129.    }
  130.  
  131.  
  132. /*
  133.  * CPAppend
  134.  *
  135.  * Append a character to the end of a string.
  136.  *
  137.  * A SysError may occur.
  138.  */
  139. void CPAppend (U,C)
  140.    register CharPtr *U;
  141.    char C;
  142.    {
  143.       if (U->CPCount-- == 0)
  144.      if (C == '\0') return;
  145.      else {
  146.         register StrPtr S = NewSCell ();
  147.         if (SysError) return;
  148.         else {
  149.            U->CPChar = S->StrChar;
  150.            if (*U->CPStr == NULL) {
  151.           U->CPSeg = (*U->CPStr = S);           /* Append head segment */
  152.           U->CPCount = StrHeadLen-1;
  153.            } else {
  154.           U->CPSeg = (U->CPSeg->StrNext = S); /* Append tail segment */
  155.           U->CPCount = StrTailLen-1;
  156.            }
  157.         }
  158.      }
  159.       *U->CPChar++ = C;
  160.    }
  161.  
  162.  
  163. /*
  164.  * LenStr
  165.  *
  166.  * Find the length of a FP string
  167.  * 
  168.  * Input
  169.  *     S = IFP string
  170.  *
  171.  * Output
  172.  *    result = length of string in characters
  173.  */
  174. FPint LenStr (S)
  175.    register StrPtr S;
  176.    {
  177.       register int J = StrHeadLen;
  178.       register FPint K = 0;
  179.       register char *T;
  180.  
  181.       for (; S!=NULL; S = S->StrNext) {
  182.      for (T = S->StrChar; --J >= 0 && *T; T++) K++;
  183.      J = StrTailLen;
  184.       }
  185.       return K;
  186.    }
  187.  
  188.  
  189. /*
  190.  * DelSPtr
  191.  *
  192.  * Delete a string pointer: decrement reference count and remove string
  193.  * if reference count is zero.
  194.  */
  195. void DelSPtr (S)
  196.    register StrPtr S;
  197.    {
  198.       register StrPtr T;
  199.  
  200.       semaphore_wait (SRefSemaphore);
  201.       if (S != NULL && !-- S->SRef) {
  202.      for (T=S; T->StrChar[0]='\0', T->StrNext!=NULL; T=T->StrNext) continue;
  203.      T->StrNext = FreeString;
  204.      FreeString = S;
  205.       }
  206.       semaphore_signal (SRefSemaphore);
  207.    }
  208.  
  209. /*
  210.  * NewString
  211.  *
  212.  * Make a copy of a string.  The old string retains its reference count.
  213.  *
  214.  * Input
  215.  *    S = pointer to string
  216.  *
  217.  * Output
  218.  *    result = pointer to new string
  219.  *
  220.  * A SysError may occur, in which case NULL is returned.
  221.  */
  222. private StrPtr NewString (S)
  223.    register StrPtr S;
  224.    {
  225.       extern char *strncpy ();
  226.       register StrPtr R,T;
  227.  
  228.       if (S == NULL) return NULL;
  229.       R = T = NewSCell ();   /* R = root of copy */
  230.       if (SysError) return NULL;
  231.       (void) strncpy (T->StrChar,S->StrChar,StrHeadLen);
  232.       while ((S=S->StrNext) != NULL) {
  233.      T->StrNext = NewSCell ();
  234.      T = T->StrNext;
  235.      (void) strncpy (T->StrChar,S->StrChar,StrTailLen);
  236.      if (SysError) {
  237.         DelSPtr (R);   /* flush copy */
  238.         return NULL;
  239.      }
  240.       }
  241.       return R;
  242.    }
  243.  
  244.  
  245. /*
  246.  * MakeString
  247.  *
  248.  * Make an IFP string from a C string.
  249.  *
  250.  * Input
  251.  *      S = pointer to character array terminated by '\0'
  252.  *
  253.  * Output
  254.  *      result = pointer to IFP (segmented) string
  255.  *
  256.  * A SysError may occur, in which case a NULL pointer is returned.
  257.  */
  258. StrPtr MakeString (S)
  259.    char *S;
  260.    {
  261.       extern char *strncpy ();
  262.       int L=strlen(S);
  263.  
  264.       if (L <= 0) return NULL;
  265.       else {
  266.          StrPtr R,T;
  267.      int N = StrHeadLen;
  268.      R = T = NewSCell ();                /* R = root of copy */
  269.      if (SysError) return NULL;
  270.      while (1) {
  271.         (void) strncpy (T->StrChar,S,N);
  272.         if ((L -= N) <= 0) return R;
  273.         else {
  274.            S += N;
  275.            T->StrNext = NewSCell ();
  276.            if (SysError) {
  277.           DelSPtr (R);   /* flush copy */
  278.           return NULL;
  279.            }
  280.            T = T->StrNext;
  281.            N = StrTailLen;
  282.         }
  283.      }
  284.       }
  285.    }
  286.  
  287. /*
  288.  * StrComp
  289.  *
  290.  * Compares two strings.  Returns P-Q
  291.  */
  292. int StrComp (P,Q)
  293.    StrPtr P,Q;
  294.    {
  295.       register int Diff,Len;
  296.       Len = StrHeadLen;
  297.       while (1) {
  298.      if (Q == NULL) return P!=NULL;
  299.      else if (P == NULL) return -(Q!=NULL);
  300.      else if (Diff = strncmp (P->StrChar,Q->StrChar,Len)) return Diff;
  301.      else {
  302.         Len = StrTailLen;
  303.         P = P->StrNext;
  304.         Q = Q->StrNext;
  305.      }
  306.       }
  307.    }
  308.  
  309.  
  310. /*
  311.  * Make a copy of a non-null string pointer, incrementing the reference count.
  312.  *
  313.  * A SysError may occur, in in which case a NULL pointer is returned.
  314.  */
  315. StrPtr CopySPtr (S)
  316.    StrPtr S;
  317.    {
  318.       semaphore_wait (SRefSemaphore);
  319.       if (S != NULL && !++S->SRef) {
  320.      S->SRef--;
  321.      S = NewString (S);
  322.       }
  323.       semaphore_signal (SRefSemaphore);
  324.       return S;
  325.    }
  326.  
  327. /*
  328.  * InitString
  329.  *
  330.  * Initialize this module
  331.  */
  332. void InitString ()
  333.    {
  334.       int C; 
  335.       StrPtr S;
  336.  
  337.       CharString = (StrPtr *) malloc (128 * sizeof (StrPtr));
  338.       CharString [0] = NULL;
  339.       for (C = 1; C<128; C++) {
  340.      CharString [C] = S = NewSCell ();
  341.      S->StrChar [0] = C;
  342.      S->StrChar [1] = '\0';
  343.       }
  344.    }
  345.  
  346. /************************** end of string.c **************************/
  347.  
  348.